package de.e2it3t.schulverwaltung.ui;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.validation.ValidationResult;
import com.jgoodies.validation.ValidationResultModel;
import com.jgoodies.validation.util.DefaultValidationResultModel;
import com.jgoodies.validation.view.ValidationResultViewFactory;
import de.e2it3t.schulverwaltung.App;
import de.e2it3t.schulverwaltung.data.Klasse;
import de.e2it3t.schulverwaltung.data.Lehrblock;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * Dialog für das Hinzufügen und Bearbeiten eines Lehrblocks.
 * 
 * @author Viktor Reiser
 */
public class LehrblockDialog extends JDialog {
    
    private AppView owner;
    
    private Lehrblock lehrblock;
    
    private JButton saveButton;
    private JButton cancelButton;
    private JComboBox klassenComboBox;
    private JComboBox kalenderwocheComboBox;
    private JSpinner jahrSpinner;
    
    private ValidationResultModel validationModel;
    
    
    public LehrblockDialog(AppView owner) {
        this(owner, 0);
    }
    
    public LehrblockDialog(AppView owner, int lehrblockId) {
        super();
        
        setTitle("Neuer Lehrblock");
        setModal(true);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setMinimumSize(new Dimension(200, 100));
        
        this.owner = owner;
        
        if (lehrblockId != 0) {
            lehrblock = App.getDatabase().getLehrblock(lehrblockId);
            
            if (lehrblock != null) {
                setTitle("Lehrblock bearbeiten");
            }
        }
        
        // Modell, welches Validierungsfehler erhält und diese in eine
        // Liste im Dialog füllt
        validationModel = new DefaultValidationResultModel();
        
        setupUi();
        
        // gewünschte Größe des Dialog berechnen und setzen
        pack();
        // Dialog ist auf eine Größe fixiert
        setResizable(false);
        // Dialog in die Mitte des Bildschirms bringen
        setLocationRelativeTo(null);
    }
    
    private void setupUi() {
        setupUiComponents();
        setupLehrblock();
        
        
        // Liste der Validierungmeldungen erstellen
        JComponent errorList = ValidationResultViewFactory.createReportList(
                validationModel);
        errorList.setPreferredSize(new Dimension(10, 50));
        
        JPanel content = new JPanel();
        content.setBorder(new EmptyBorder(10, 10, 10, 10));
        content.setLayout(new FormLayout(
                "pref, 5px, pref, 5px, pref",
                "pref, 5px, pref, 5px, pref, 5px, pref, 15px, pref"));
        CellConstraints cc = new CellConstraints();
        
        content.add(new JLabel("Klasse"), cc.xy(1, 1));
        content.add(klassenComboBox, cc.xywh(3, 1, 3, 1));
        content.add(new JLabel("Jahr"), cc.xy(1, 3));
        content.add(jahrSpinner, cc.xywh(3, 3, 3, 1));
        content.add(new JLabel("Kalenderwoche"), cc.xy(1, 5));
        content.add(kalenderwocheComboBox, cc.xywh(3, 5, 3, 1));
        content.add(errorList, cc.xywh(1, 7, 5, 1));
        content.add(saveButton, cc.xy(3, 9));
        content.add(cancelButton, cc.xy(5, 9));
        
        setLayout(new BorderLayout());
        add(content, BorderLayout.CENTER);
    }
    
    private void setupUiComponents() {
        saveButton = new JButton("Speichern");
        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                validateAndSave();
            }
        });
        
        cancelButton = new JButton("Abbrechen");
        cancelButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // wir zerstören den Dialog einfach
                dispose();
            }
        });
        
        klassenComboBox = new JComboBox(
                App.getDatabase().getKlassen().toArray(new Klasse [0]));
        jahrSpinner = new JSpinner(new SpinnerNumberModel(2013, 2000, 2200, 1));
        jahrSpinner.setEditor(new JSpinner.NumberEditor(jahrSpinner, "#"));
        jahrSpinner.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                updateKalenderWochenComboBox();
            }
        });
        kalenderwocheComboBox = new JComboBox();
        
        updateKalenderWochenComboBox();
    }
    
    private void updateKalenderWochenComboBox() {
        int previous = kalenderwocheComboBox.getSelectedIndex();
        
        kalenderwocheComboBox.removeAllItems();
        
        Calendar cal = new GregorianCalendar(Locale.GERMANY);
        cal.clear();
        cal.set(Calendar.YEAR, (Integer)jahrSpinner.getValue());
        cal.set(Calendar.WEEK_OF_YEAR, 1);
        
        if (cal.get(Calendar.WEEK_OF_YEAR) == 2) {
            cal.add(Calendar.DATE, -7);
        }
        
        SimpleDateFormat sdfWeek = new SimpleDateFormat("ww", Locale.GERMANY);
        SimpleDateFormat sdfDate = new SimpleDateFormat("d. MMM ", Locale.GERMANY);
        
        for (int i = 0; i < 53; i++) {
            StringBuilder sb = new StringBuilder();
            
            sb.append("KW ");
            sb.append(sdfWeek.format(cal.getTime()));
            sb.append(" | ");
            sb.append(sdfDate.format(cal.getTime()));
            sb.append(" - ");
            
            cal.add(Calendar.DATE, 6);
            
            sb.append(sdfDate.format(cal.getTime()));
            
            kalenderwocheComboBox.addItem(sb.toString());
            
            cal.add(Calendar.DATE, 1);
            
            if (cal.get(Calendar.WEEK_OF_YEAR) == 1) {
                break;
            }
        }
        
        kalenderwocheComboBox.setSelectedIndex(
                Math.max(0, Math.min(kalenderwocheComboBox.getItemCount() - 1, previous)));
    }
    
    private void setupLehrblock() {
        if (lehrblock == null) {
            return;
        }
        
        for (int i = 0; i < klassenComboBox.getItemCount(); i++) {
            if (((Klasse)klassenComboBox.getItemAt(i)).getId() == lehrblock.getKlasseId()) {
                klassenComboBox.setSelectedIndex(i);
                break;
            }
        }
        
        jahrSpinner.setValue(lehrblock.getJahr());
        kalenderwocheComboBox.setSelectedIndex(lehrblock.getKalenderwoche() - 1);
    }
    
    
    private void validateAndSave() {
        ValidationResult result = new ValidationResult();
        Lehrblock saveLehrblock = new Lehrblock();
        
        if (lehrblock != null) {
            saveLehrblock.setId(lehrblock.getId());
        }
        
        saveLehrblock.setJahr((Integer)jahrSpinner.getValue());
        saveLehrblock.setKlasseId(((Klasse)klassenComboBox.getSelectedItem()).getId()); 
        saveLehrblock.setKalenderwoche(kalenderwocheComboBox.getSelectedIndex() + 1);
        
        if (App.getDatabase().hasLehrblock(saveLehrblock)) {
            result.addError("Die Klasse hat bereits in dieser Woche Unterricht");
        }
        
        validationModel.setResult(result);
        pack();
        
        if (result.isEmpty()) {
            App.getDatabase().saveLehrblock(saveLehrblock);
            owner.refreshView();
            dispose();
        }
    }
}
